Dansk

Lær at skabe kraftfulde API-endepunkter med Next.js Route Handlers. Denne guide dækker alt fra grundlæggende opsætning til avancerede teknikker med praktiske eksempler og best practices.

Next.js Route Handlers: En Komplet Guide til Oprettelse af API-Endepunkter

Next.js har revolutioneret den måde, vi bygger webapplikationer på med sine kraftfulde funktioner som server-side rendering, statisk site-generering og nu, Route Handlers. Route Handlers giver en fleksibel og effektiv måde at oprette API-endepunkter direkte i din Next.js-applikation. Denne guide udforsker konceptet Route Handlers, deres fordele, og hvordan man effektivt bruger dem til at bygge robuste API'er.

Hvad er Next.js Route Handlers?

Route Handlers er funktioner, der er defineret i app-mappen i et Next.js-projekt, og som håndterer indkommende HTTP-forespørgsler. I modsætning til den ældre pages/api-tilgang (som bruger API Routes), tilbyder Route Handlers en mere strømlinet og fleksibel måde at definere API-endepunkter på sammen med dine React-komponenter. De er i bund og grund serverless funktioner, der udføres på edge-netværket eller i dit valgte servermiljø.

Tænk på Route Handlers som backend-logikken i din Next.js-applikation, der er ansvarlig for at behandle forespørgsler, interagere med databaser og returnere svar.

Fordele ved at Bruge Route Handlers

Opsætning af dit Next.js-projekt

Før du dykker ned i Route Handlers, skal du sikre dig, at du har et Next.js-projekt opsat med app-mappen. Hvis du starter et nyt projekt, skal du bruge følgende kommando:

npx create-next-app@latest my-nextjs-app

Vælg app-mappen under opsætningsprocessen for at aktivere det nye routing-system.

Oprettelse af din Første Route Handler

Lad os oprette et simpelt API-endepunkt, der returnerer et JSON-svar. Opret en ny mappe i app-mappen, for eksempel /app/api/hello. I denne mappe skal du oprette en fil ved navn route.ts (eller route.js, hvis du ikke bruger TypeScript).

Her er koden til din første Route Handler:

// app/api/hello/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });
}

Forklaring:

Nu kan du tilgå dette endepunkt ved at navigere til /api/hello i din browser eller ved at bruge et værktøj som curl eller Postman.

Håndtering af Forskellige HTTP-Metoder

Route Handlers understøtter forskellige HTTP-metoder som GET, POST, PUT, DELETE, PATCH og OPTIONS. Du kan definere separate funktioner for hver metode i den samme route.ts-fil.

// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // Logik til at hente alle brugere fra databasen
 const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Eksempeldata
 return NextResponse.json(users);
}

export async function POST(request: Request) {
 const data = await request.json(); // Parse forespørgslens body som JSON
 // Logik til at oprette en ny bruger i databasen ved hjælp af 'data'
 const newUser = { id: 3, name: data.name, email: data.email }; // Eksempel
 return NextResponse.json(newUser, { status: 201 }); // Returner den nye bruger med en 201 Created statuskode
}

Forklaring:

Adgang til Forespørgselsdata

request-objektet giver adgang til forskellige oplysninger om den indkommende forespørgsel, herunder headers, query-parametre og request body.

Headers

Du kan få adgang til request headers ved hjælp af request.headers-egenskaben:

export async function GET(request: Request) {
 const userAgent = request.headers.get('user-agent');
 console.log('User Agent:', userAgent);
 return NextResponse.json({ userAgent });
}

Query-parametre

For at få adgang til query-parametre kan du bruge URL-konstruktøren:

export async function GET(request: Request) {
 const url = new URL(request.url);
 const searchParams = new URLSearchParams(url.search);
 const id = searchParams.get('id');
 console.log('ID:', id);
 return NextResponse.json({ id });
}

Request Body

For POST-, PUT- og PATCH-forespørgsler kan du få adgang til request body ved hjælp af metoderne request.json() eller request.text(), afhængigt af content-typen.

export async function POST(request: Request) {
 const data = await request.json();
 console.log('Data:', data);
 return NextResponse.json({ receivedData: data });
}

Returnering af Svar

NextResponse-objektet bruges til at konstruere API-svar. Det tilbyder flere metoder til at indstille headers, statuskoder og svar-bodies.

JSON-svar

Brug NextResponse.json()-metoden til at returnere JSON-svar:

return NextResponse.json({ message: 'Success!', data: { name: 'John Doe' } }, { status: 200 });

Tekstsvar

Brug new Response()-konstruktøren til at returnere rene tekstsvar:

return new Response('Hello, world!', { status: 200, headers: { 'Content-Type': 'text/plain' } });

Omdirigeringer

Brug NextResponse.redirect() til at omdirigere brugere til en anden URL:

import { redirect } from 'next/navigation';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.redirect(new URL('/new-location', request.url));
}

Indstilling af Headers

Du kan indstille brugerdefinerede headers ved hjælp af headers-optionen i NextResponse.json() eller new Response():

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });

Middleware-integration

Middleware giver dig mulighed for at køre kode, før en forespørgsel håndteres af din Route Handler. Dette er nyttigt til autentificering, autorisation, logning og andre tværgående anliggender.

For at oprette middleware skal du oprette en fil ved navn middleware.ts (eller middleware.js) i app-mappen eller en undermappe. Middlewaren vil gælde for alle ruter i den pågældende mappe og dens undermapper.

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url));
 }

 return NextResponse.next();
}

export const config = {
 matcher: ['/protected/:path*'], // Anvend denne middleware på stier, der starter med /protected/
};

Forklaring:

Fejlhåndtering

Korrekt fejlhåndtering er afgørende for at bygge robuste API'er. Du kan bruge try...catch-blokke til at håndtere undtagelser og returnere passende fejlsvar.

export async function GET(request: Request) {
 try {
 // Simuler en fejl
 throw new Error('Something went wrong!');
 } catch (error: any) {
 console.error('Error:', error);
 return NextResponse.json({ error: error.message }, { status: 500 });
 }
}

Forklaring:

Streaming af Svar

Route Handlers understøtter streaming af svar, hvilket giver dig mulighed for at sende data inkrementelt til klienten. Dette er især nyttigt for store datasæt eller langvarige processer.

import { Readable } from 'stream';
import { NextResponse } from 'next/server';

async function* generateData() {
 for (let i = 0; i < 10; i++) {
 await new Promise(resolve => setTimeout(resolve, 500)); // Simuler forsinkelse
 yield `Data chunk ${i}\n`;
 }
}

export async function GET(request: Request) {
 const readableStream = Readable.from(generateData());

 return new Response(readableStream, {
 headers: { 'Content-Type': 'text/plain; charset=utf-8' },
 });
}

Forklaring:

Autentificering og Autorisation

At sikre dine API-endepunkter er afgørende. Du kan implementere autentificering og autorisation ved hjælp af middleware eller direkte i dine Route Handlers.

Autentificering

Autentificering verificerer identiteten af den bruger, der sender forespørgslen. Almindelige autentificeringsmetoder inkluderer:

Her er et eksempel på JWT-autentificering ved hjælp af middleware:

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import jwt from 'jsonwebtoken';

const secret = process.env.JWT_SECRET || 'your-secret-key'; // Erstat med en stærk, tilfældigt genereret hemmelighed

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token')?.value;

 if (!token) {
 return NextResponse.json({ message: 'Authentication required' }, { status: 401 });
 }

 try {
 jwt.verify(token, secret);
 return NextResponse.next();
 } catch (error) {
 return NextResponse.json({ message: 'Invalid token' }, { status: 401 });
 }
}

export const config = {
 matcher: ['/api/protected/:path*'],
};

Autorisation

Autorisation bestemmer, hvilke ressourcer en bruger har adgang til. Dette er typisk baseret på roller eller tilladelser.

Du kan implementere autorisation i dine Route Handlers ved at tjekke brugerens roller eller tilladelser og returnere en fejl, hvis de ikke har adgang.

// app/api/admin/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // Antag, at du har en funktion til at hente brugerens rolle fra tokenet eller sessionen
 const userRole = await getUserRole(request);

 if (userRole !== 'admin') {
 return NextResponse.json({ message: 'Unauthorized' }, { status: 403 });
 }

 // Logik til at hente admin-data
 const adminData = { message: 'Admin data' };
 return NextResponse.json(adminData);
}

async function getUserRole(request: Request): Promise {
 // Erstat med din faktiske logik til at udtrække brugerens rolle fra forespørgslen
 // Dette kan involvere verificering af et JWT-token eller tjek af en session
 return 'admin'; // Eksempel: hårdkodet rolle til demonstration
}

Implementering af Route Handlers

Route Handlers implementeres som serverless funktioner hos din valgte hostingudbyder. Next.js understøtter forskellige implementeringsplatforme, herunder Vercel, Netlify, AWS og flere.

For Vercel er implementering så simpelt som at forbinde dit Git-repository til Vercel og pushe din kode. Vercel registrerer automatisk dit Next.js-projekt og implementerer dine Route Handlers som serverless funktioner.

Avancerede Teknikker

Edge Functions

Route Handlers kan implementeres som Edge Functions, som udføres på kanten af et CDN, tættere på dine brugere. Dette kan markant reducere latenstid og forbedre ydeevnen.

For at implementere en Route Handler som en Edge Function, skal du tilføje edge-runtime til din route.ts-fil:

export const runtime = 'edge';

import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from the Edge!' });
}

Server Actions

Server Actions giver dig mulighed for at udføre server-side kode direkte fra dine React-komponenter. Route Handlers og Server Actions fungerer problemfrit sammen, hvilket gør det let at bygge komplekse applikationer.

Her er et eksempel på brug af en Server Action til at kalde en Route Handler:

// app/components/MyComponent.tsx
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';

async function handleSubmit(data: FormData) {
 'use server';

 const name = data.get('name');
 const email = data.get('email');

 const response = await fetch('/api/users', {
 method: 'POST',
 body: JSON.stringify({ name, email }),
 });

 if (response.ok) {
 router.refresh(); // Opdater siden for at afspejle ændringerne
 }
}

export default function MyComponent() {
 const router = useRouter();

 return (
 




); }

Caching

Caching kan markant forbedre ydeevnen af dine API-endepunkter. Du kan bruge Cache-Control-headeren til at styre, hvordan dine svar caches af browsere og CDN'er.

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });

Dette eksempel indstiller Cache-Control-headeren til public, max-age=3600, hvilket fortæller browsere og CDN'er, at de skal cache svaret i en time.

Best Practices

Eksempler fra den Virkelige Verden

Her er et par eksempler fra den virkelige verden på, hvordan Route Handlers kan bruges:

Eksempel på international e-handel: En Route Handler, der bruges til at hente produktpriser baseret på brugerens land. Endepunktet kunne bruge forespørgslens geolocation (afledt af IP-adresse) til at bestemme brugerens placering og returnere priser i den relevante valuta. Dette bidrager til en lokaliseret shoppingoplevelse.

Eksempel på global autentificering: En Route Handler, der implementerer multi-faktor-autentificering (MFA) for brugere verden over. Dette kunne involvere afsendelse af SMS-koder eller brug af authenticator-apps, alt imens forskellige regioners privatlivsregler og telekommunikationsinfrastrukturer respekteres.

Levering af flersproget indhold: En Route Handler, der leverer indhold på brugerens foretrukne sprog. Dette kan bestemmes ud fra Accept-Language-headeren i forespørgslen. Dette eksempel fremhæver behovet for korrekt UTF-8-kodning og understøttelse af sprog, der læses fra højre mod venstre, hvor det er relevant.

Konklusion

Next.js Route Handlers tilbyder en kraftfuld og fleksibel måde at oprette API-endepunkter direkte i din Next.js-applikation. Ved at udnytte Route Handlers kan du nemt bygge robuste API'er, samlokalisere din backend-logik med dine React-komponenter og drage fordel af funktioner som middleware, streaming og Edge Functions.

Denne omfattende guide har dækket alt fra grundlæggende opsætning til avancerede teknikker. Ved at følge de bedste praksisser, der er beskrevet i denne guide, kan du bygge API'er af høj kvalitet, der er sikre, performante og vedligeholdelsesvenlige.